/**
 * MCU 厂家 SDK 中使用的 OS 适配层
 * Copyright (c) 2021 深圳市智辰科技有限公司
 * All rights reserved.
 */

#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include "os.h"


/**
 * @brief 关于临界区
 * FreeRTOS@ESP32 有几种层次的临界区：
 * 硬件级：硬件(仅可屏蔽的)中断开关: portDISABLE_INTERRUPTS() / portENABLE_INTERRUPTS() =实现=> taskDISABLE_INTERRUPTS() / taskENABLE_INTERRUPTS()
 * 任务级：可在任务执行过程中禁止任务切换: vTaskSuspendAll() / xTaskResumeAll()
 * 资源级: 仅针对指定资源进行保护: vTaskEnterCritical() / vTaskExitCritical() =实现=> portENTER_CRITICAL() / portEXIT_CRITICAL() =代替=> taskENTER_CRITICAL() / taskEXIT_CRITICAL()
 * NONOS 中的 osCritical 是针对单个资源级的
 * 关于 vTaskEnterCritical() 可能导致的问题，请参见：
 * @see https://docs.espressif.com/projects/esp-idf/zh_CN/latest/api-guides/freertos-smp.html#critical-sections-disabling-interrupts
 */
/*
// 用 portENTER_CRITICAL()/portEXIT_CRITICAL() 的实现会关闭中断，导致很多场景下无法使用，放弃！
#define osCritical           portMUX_TYPE
//#define osCriticalInitValue  portMUX_INITIALIZER_UNLOCKED
#define osCriticalInitValue  {portMUX_FREE_VAL, 0}
#define osCriticalDef(css)   osCritical (css) = osCriticalInitValue
#define osCriticalEnter(css) portENTER_CRITICAL_SAFE(&(css))
#define osCriticalLeave(css) portEXIT_CRITICAL_SAFE(&(css))
*/
// 改为 用 Binary 型的 Semaphore 实现
osCritical osCriticalCreate() {
	return xSemaphoreCreateBinary();
}

void osCriticalEnter(osCritical css) {
	xSemaphoreTake((QueueHandle_t)css, (TickType_t)100);
}

void osCriticalLeave(osCritical css) {
	xSemaphoreGive((QueueHandle_t)css);
}

/// 销毁一个临界区
void osCriticalDelete(osCritical css) {
	vSemaphoreDelete((QueueHandle_t)css);
}

/// @brief 重启
void osReboot(void) {
	esp_restart();
}

/// @brief 喂看门狗
void osFeedWatchdog(void) {
	esp_task_wdt_reset();
}
